﻿#ifdef _WIN32
#include "windows_defines.h"
#endif

#include "../../../../../../unittest/framework/unittest.hh"
#include "box/service_context.hh"
#include "box/service_box.hh"
#include "redis/redis.hh"

#include "../src/util/time_util.hh"

#include <iostream>

FIXTURE_BEGIN(test_redis)

SETUP([]() {
})

CASE(TestRedis1) {
    kratos::service::ServiceBox service_box;
    const char *argv_service[] = {"test_redis",
                                  "--config=config_service_box.cfg",
                                  "--proxy-host=127.0.0.1:10002"};
    ASSERT_TRUE(service_box.start(3, argv_service));

    auto ctx = service_box.get_context();
    ASSERT_TRUE(ctx != nullptr);
    
    auto redis_ptr = ctx->new_redis();
    ASSERT_TRUE(redis_ptr);

    ASSERT_TRUE(redis_ptr->add_host("test", "127.0.0.1", 6379, "", ""));
    ASSERT_TRUE(redis_ptr->start());

    ASSERT_TRUE(redis_ptr->do_command("test", "set k1 2", 1000, [&](const kratos::redis::Result& result, uint64_t v) {
        std::cout << "result=" << result.is_success() << " v=" << v << '\n';
    }, 0));
    
    ASSERT_FALSE(redis_ptr->do_command("test_", "set k1 2", 1000, [&](const kratos::redis::Result& result, uint64_t v) {
        std::cout << "result=" << result.is_success() << " v=" << v << '\n';
    }, 0));

    service_box.stop();
}

CASE(TestRedis2) {
    kratos::service::ServiceBox service_box;
    const char *argv_service[] = {"test_redis",
                                  "--config=config_service_box.cfg",
                                  "--proxy-host=127.0.0.1:10002"};
    ASSERT_TRUE(service_box.start(3, argv_service));

    auto ctx = service_box.get_context();
    ASSERT_TRUE(ctx != nullptr);
    
    auto redis_ptr = ctx->new_redis();
    ASSERT_TRUE(redis_ptr);

    ASSERT_TRUE(redis_ptr->add_host("test", "127.0.0.1", 6379, "", ""));
    ASSERT_TRUE(redis_ptr->start());

    coro_start([&](void *) {
        auto ret = redis_ptr->do_command_co("test", "get k1", 1000);
        ASSERT_TRUE(ret);
        ASSERT_TRUE(ret->is_success());
        std::string value;
        ret->get_return(value);
        std::cout << "value=" << value << '\n';
    });
    
    coro_start([&](void *) {
        auto ret = redis_ptr->do_command_co("test_", "get k1", 1000);
        ASSERT_FALSE(ret);
    });

    auto start = kratos::util::get_os_time_millionsecond();
    while (true)
    {
        auto ms = kratos::util::get_os_time_millionsecond();
        if (ms - start > 1000)
        {
            break;
        }
        redis_ptr->update(ms);
    }

    service_box.stop();
}

CASE(TestRedis3) {
    kratos::service::ServiceBox service_box;
    const char *argv_service[] = {"test_redis",
                                  "--config=config_service_box.cfg",
                                  "--proxy-host=127.0.0.1:10002"};
    ASSERT_TRUE(service_box.start(3, argv_service));

    auto ctx = service_box.get_context();
    ASSERT_TRUE(ctx != nullptr);
    
    auto redis_ptr = ctx->new_redis();
    ASSERT_TRUE(redis_ptr);

    ASSERT_TRUE(redis_ptr->add_host("test", "127.0.0.1", 6379, "", ""));
    ASSERT_TRUE(redis_ptr->start());

    coro_start([&](void *) {
        auto ret = redis_ptr->do_command_co("test", "get k2", 1000);
        ASSERT_TRUE(ret);
        ASSERT_TRUE(ret->is_success());
        std::string value;
        ret->get_return(value);
        std::cout << "value=" << value << '\n';
    });

    auto start = kratos::util::get_os_time_millionsecond();
    while (true)
    {
        auto ms = kratos::util::get_os_time_millionsecond();
        if (ms - start > 1000)
        {
            break;
        }
        redis_ptr->update(ms);
    }

    service_box.stop();

}

FIXTURE_END(test_redis)